/**
 * tools/definitions.ts
 * MCP tool definitions for Apple Reminders server, adhering to standard JSON Schema.
 */

import type { Tool } from '@modelcontextprotocol/sdk/types.js';
import {
  CALENDAR_ACTIONS,
  DUE_WITHIN_OPTIONS,
  LIST_ACTIONS,
  REMINDER_ACTIONS,
} from '../types/index.js';

/**
 * Extended JSON Schema with dependentSchemas support
 * This extends the base schema type to include the JSON Schema Draft 2019-09 dependentSchemas keyword
 */
interface ExtendedJSONSchema {
  type?: string;
  properties?: Record<string, unknown>;
  required?: string[];
  dependentSchemas?: Record<string, unknown>;
  enum?: unknown[];
  description?: string;
  default?: unknown;
  format?: string;
}

/**
 * Extended Tool type that supports dependentSchemas in inputSchema
 */
interface ExtendedTool {
  name: string;
  description?: string;
  inputSchema: ExtendedJSONSchema;
}

const _EXTENDED_TOOLS: ExtendedTool[] = [
  {
    name: 'reminders_tasks',
    description:
      'Manages reminder tasks. Supports reading, creating, updating, and deleting reminders.',
    inputSchema: {
      type: 'object',
      properties: {
        action: {
          type: 'string',
          enum: REMINDER_ACTIONS,
          description: 'The operation to perform.',
        },
        // ID-based operations
        id: {
          type: 'string',
          description:
            'The unique identifier of the reminder (REQUIRED for update, delete; optional for read to get single reminder).',
        },
        // Creation/Update properties
        title: {
          type: 'string',
          description:
            'The title of the reminder (REQUIRED for create, optional for update).',
        },
        dueDate: {
          type: 'string',
          description:
            "Due date. RECOMMENDED format: 'YYYY-MM-DD HH:mm:ss' (local time without timezone, e.g., '2025-11-04 18:00:00'). Also supports: 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ss', or ISO 8601 with timezone (e.g., '2025-10-30T04:00:00Z'). When no timezone is specified, the time is interpreted as local time.",
        },
        note: {
          type: 'string',
          description: 'Additional notes for the reminder.',
        },
        url: {
          type: 'string',
          description: 'A URL to associate with the reminder.',
          format: 'uri',
        },
        completed: {
          type: 'boolean',
          description: 'The completion status of the reminder (for update).',
        },
        targetList: {
          type: 'string',
          description: 'The name of the list for create or update operations.',
        },
        // Read filters
        filterList: {
          type: 'string',
          description: 'Filter reminders by a specific list name.',
        },
        showCompleted: {
          type: 'boolean',
          description: 'Include completed reminders in the results.',
          default: false,
        },
        search: {
          type: 'string',
          description: 'A search term to filter reminders by title or notes.',
        },
        dueWithin: {
          type: 'string',
          enum: DUE_WITHIN_OPTIONS,
          description: 'Filter reminders by a due date range.',
        },
      },
      required: ['action'],
      dependentSchemas: {
        action: {
          oneOf: [
            { properties: { action: { const: 'read' } } },
            {
              properties: { action: { const: 'create' } },
              required: ['title'],
            },
            { properties: { action: { const: 'update' } }, required: ['id'] },
            { properties: { action: { const: 'delete' } }, required: ['id'] },
          ],
        },
      },
    },
  },
  {
    name: 'reminders_lists',
    description:
      'Manages reminder lists. Supports reading, creating, updating, and deleting reminder lists.',
    inputSchema: {
      type: 'object',
      properties: {
        action: {
          type: 'string',
          enum: LIST_ACTIONS,
          description: 'The operation to perform on a list.',
        },
        name: {
          type: 'string',
          description:
            'The current name of the list (for update, delete) or the name of the new list (for create).',
        },
        newName: {
          type: 'string',
          description: 'The new name for the list (for update).',
        },
      },
      required: ['action'],
      dependentSchemas: {
        action: {
          oneOf: [
            { properties: { action: { const: 'read' } } },
            { properties: { action: { const: 'create' } }, required: ['name'] },
            {
              properties: { action: { const: 'update' } },
              required: ['name', 'newName'],
            },
            { properties: { action: { const: 'delete' } }, required: ['name'] },
          ],
        },
      },
    },
  },
  {
    name: 'calendar_events',
    description:
      'Manages calendar events (time blocks). Supports reading, creating, updating, and deleting calendar events.',
    inputSchema: {
      type: 'object',
      properties: {
        action: {
          type: 'string',
          enum: CALENDAR_ACTIONS,
          description: 'The operation to perform.',
        },
        // ID-based operations
        id: {
          type: 'string',
          description:
            'The unique identifier of the event (REQUIRED for update, delete; optional for read to get single event).',
        },
        // Creation/Update properties
        title: {
          type: 'string',
          description:
            'The title of the event (REQUIRED for create, optional for update).',
        },
        startDate: {
          type: 'string',
          description:
            "Start date and time. RECOMMENDED format: 'YYYY-MM-DD HH:mm:ss' (local time without timezone, e.g., '2025-11-04 09:00:00'). Also supports: 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ss', or ISO 8601 with timezone. When no timezone is specified, the time is interpreted as local time.",
        },
        endDate: {
          type: 'string',
          description:
            "End date and time. RECOMMENDED format: 'YYYY-MM-DD HH:mm:ss' (local time without timezone, e.g., '2025-11-04 10:00:00'). Also supports: 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ss', or ISO 8601 with timezone. When no timezone is specified, the time is interpreted as local time.",
        },
        note: {
          type: 'string',
          description: 'Additional notes for the event.',
        },
        location: {
          type: 'string',
          description: 'Location for the event.',
        },
        url: {
          type: 'string',
          description: 'A URL to associate with the event.',
          format: 'uri',
        },
        isAllDay: {
          type: 'boolean',
          description: 'Whether the event is an all-day event.',
        },
        targetCalendar: {
          type: 'string',
          description:
            'The name of the calendar for create or update operations.',
        },
        // Read filters
        filterCalendar: {
          type: 'string',
          description: 'Filter events by a specific calendar name.',
        },
        search: {
          type: 'string',
          description:
            'A search term to filter events by title, notes, or location.',
        },
      },
      required: ['action'],
      dependentSchemas: {
        action: {
          oneOf: [
            { properties: { action: { const: 'read' } } },
            {
              properties: { action: { const: 'create' } },
              required: ['title', 'startDate', 'endDate'],
            },
            { properties: { action: { const: 'update' } }, required: ['id'] },
            { properties: { action: { const: 'delete' } }, required: ['id'] },
          ],
        },
      },
    },
  },
  {
    name: 'calendar_calendars',
    description:
      'Reads calendar collections. Use to inspect available calendars before creating or updating events.',
    inputSchema: {
      type: 'object',
      properties: {
        action: {
          type: 'string',
          enum: ['read'],
          description: 'The operation to perform on calendars.',
        },
      },
      required: ['action'],
      dependentSchemas: {
        action: {
          oneOf: [{ properties: { action: { const: 'read' } } }],
        },
      },
    },
  },
];

/**
 * Export TOOLS as Tool[] for MCP server compatibility
 * The dependentSchemas are preserved at runtime even though TypeScript doesn't type-check them
 */
export const TOOLS = _EXTENDED_TOOLS as unknown as Tool[];
